using System;
using System.Collections.Generic;
using System.Text;
using Zsa.Emulation.Memory;
using System.Drawing;

namespace Zsa.Emulation.PPU
{
    /// <summary>
    /// A color palette inside the nes.
    /// </summary>
    public class PaletteTable : IMemoryStream
    {
        #region Fields
        /// <summary>
        /// The palette bytes.
        /// </summary>
        private byte[] _PaletteBytes;

        /// <summary>
        /// The color palette type.
        /// </summary>
        private ColorPaletteType _PaletteType;

        /// <summary>
        /// The color palette settings.
        /// </summary>
        private ColorPaletteSettings _PaletteSettings;

        private int _TransparentColor = Color.Pink.ToArgb();
        #endregion Fields

        #region Constructor
        /// <summary>
        /// Initializes a new instance of the <see cref="T:PaletteTable"/> class.
        /// </summary>
        /// <param name="paletteType">Type of the palette.</param>
        /// <param name="paletteSettings">The palette settings.</param>
        public PaletteTable(ColorPaletteType paletteType, ColorPaletteSettings paletteSettings)
        {
            if (paletteType != ColorPaletteType.Background &&
                paletteType != ColorPaletteType.Sprite)
            {
                throw new ArgumentException("Palette type is invalid.", "paletteType");
            }

            _PaletteType = paletteType;
            _PaletteSettings = paletteSettings;
            _PaletteBytes = new byte[16];
        }
        #endregion Constructor

        #region IMemoryStream Members

        public byte Read(ushort address)
        {
            return _PaletteBytes[address];
        }

        public byte Read(int address)
        {
            return _PaletteBytes[address];
        }

        public void Read(byte[] buffer, int address, int count)
        {
            throw new Exception("The method or operation is not implemented.");
        }

        public void Write(byte[] buffer, int address, int count)
        {
            throw new Exception("The method or operation is not implemented.");
        }

        public void Write(int address, byte romByte)
        {
            _PaletteBytes[address] = romByte;
        }

        public int Length
        {
            get
            {
                return 16;
            }
        }

        public int GetColor(int index)
        {
            if (index == 0)
            {
                return _TransparentColor;
            }
            return _PaletteSettings[
                _PaletteBytes[index]
            ];
        }

        #endregion

        public int this[int index]
        {
            get
            {
                return _PaletteSettings[
                    _PaletteBytes[index]
                ];
            }
        }


        public static PaletteTable CreateMonochrome()
        {
            return CreateMonochrome(ColorPaletteType.Background);
        }
         public static PaletteTable CreateMonochrome(ColorPaletteType paletteType)
        {
            return new PaletteTable(paletteType, ColorPaletteSettings.CreateDefault());
        }
    }
}
